﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using ExcelMergeDocs.WinClient.ViewModel;
using System.IO;
using Microsoft.Office.Interop.Excel;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using Microsoft.Win32;

namespace ExcelMergeDocs.WinClient.Services {
    public interface IDocSelectionService {
        DocViewModel LoadDocument(string filepath);

        bool MergeDocuments(System.Collections.ObjectModel.ObservableCollection<DocViewModel> Documents);
    }
    public class DocSelectionService : IDocSelectionService {
        public DocViewModel LoadDocument(string filepath) {
            var result = new DocViewModel {
                Name = Path.GetFileName(filepath),
                Filepath = filepath,
                IsExpanded = true
            };
            //
            // get worksheets

            var task = Task<IEnumerable<WSViewModel>>.Factory.StartNew(() => GetWorksheetModels(filepath));
            try {
                task.Wait();
            } catch (AggregateException ae) {
                throw ae.Flatten();
            }
            foreach (var item in task.Result) {
                result.Worksheets.Add(item);
            }
            return result;
        }

        private IEnumerable<WSViewModel> GetWorksheetModels(string filepath) {
            var worksheets = new List<WSViewModel>();
            var app = new Application();
            if (app == null) {
                throw new InvalidOperationException("Error accessing Excel.  Possibly incompatible version of office.");
            }
#if DEBUG
            app.Visible = true;
#else
            app.Visible = false;
#endif
            var workbook = app.Workbooks.Open(filepath);
            foreach (Worksheet actualsheet in workbook.Worksheets) {
                var cellcount = app.WorksheetFunction.CountA(actualsheet.Cells);
                worksheets.Add(new WSViewModel {
                    Name = actualsheet.Name,
                    IsSelected = cellcount > 0
                });
            }
            workbook.Close(false);
            app.Quit();

            return worksheets;
        }


        public bool MergeDocuments(ObservableCollection<DocViewModel> documents) {
            //var dlg = new SaveFileDialog();
            //dlg.AddExtension = true;
            //dlg.DefaultExt = ".xls";
            //dlg.CreatePrompt = true;
            //dlg.OverwritePrompt = true;
            //var result = dlg.ShowDialog();

            //if (result.HasValue && !result.Value) return false; // cancelled

            var task = Task.Factory.StartNew(() => ProcessDocuments(documents, ""));
            try {
                task.Wait();
                return true;
            } catch (AggregateException ae) {
                throw ae.Flatten();
            }
        }

        private void ProcessDocuments(ObservableCollection<DocViewModel> documents, string targetfilepath) {
            var app = new Application();
            if (app == null) {
                throw new InvalidOperationException("Error accessing Excel.  Possibly incompatible version of office.");
            }
            app.Visible = true;
            var targetbook = app.Workbooks.Add();
            var rnd = new Random();
            foreach (Worksheet item in targetbook.Worksheets) {
                item.Name = string.Format("~Merging-{0}", rnd.Next(1000, 9999));
            }
            foreach (var doc in documents) {
                var srcbook = app.Workbooks.Open(doc.Filepath);
                foreach (Worksheet worksheet in srcbook.Worksheets) {
                    if (doc.Worksheets.Any(a => a.Name == worksheet.Name && a.IsSelected)) {
                        worksheet.Copy(After: targetbook.Worksheets[targetbook.Worksheets.Count]);
                    }
                }
                srcbook.Close();
            }
            app.DisplayAlerts = false;
            foreach (Worksheet sheet in targetbook.Worksheets) {
                if (sheet.Name.Contains("~Merging-"))
                    sheet.Delete();
            }
            app.DisplayAlerts = true;
        }
    }
}
